<template>
    <div class="body">
        <header id="header">
            <h3 class="header-title">五次方可视化</h3>
            <div class="header-info header-info-l">数据来源：五次方</div>
            <div class="header-info header-info-r">数据日期：<span id="nowDate"></span></div>
        </header>

        <footer id="footer"></footer>

        <div id="container">
            <div id="flexCon">
                <div class="flex-row">
                    <div class="flex-cell flex-cell-l">
                        <div class="chart-wrapper">
                            <h3 class="chart-title">文章热门排行Top10</h3>
                            <div class="chart-div" id="rankChart">
                                <div class="chart-loader">
                                    <div class="loader"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="flex-cell flex-cell-c" style="padding-right:0;">
                        <div class="chart-wrapper">
                            <h3 class="chart-title">统计数据</h3>
                            <div class="chart-div chart-done">
                                <table class="data-t">
                                    <tr>
                                        <th><img src="@/assets/img/1.png"/></th>
                                        <td>
                                            <p><span id="browseNum">{{ statistics.browseNum }}</span></p>
                                            <p>总浏览量</p>
                                        </td>
                                        <th><img src="@/assets/img/2.png"/></th>
                                        <td>
                                            <p><span id="registerNum">{{ statistics.registerNum }}</span></p>
                                            <p>注册人数</p>
                                        </td>
                                    </tr>
                                    <tr>
                                        <th><img src="@/assets/img/3.png"/></th>
                                        <td>
                                            <p><span id="onlineNum">{{ statistics.onlineNum }}</span></p>
                                            <p>在线人数</p>
                                        </td>
                                        <th><img src="@/assets/img/4.png" style="width: 50px;height: 50px"/></th>
                                        <td>
                                            <p><span id="articleNum">{{ statistics.articleNum }}</span></p>
                                            <p>总文章数</p>
                                        </td>
                                    </tr>
                                    <tr>
                                        <th><img src="@/assets/img/5.png" style="width: 50px;height: 50px"/></th>
                                        <td>
                                            <p><span id="problemNum">{{ statistics.problemNum }}</span></p>
                                            <p>总问答数</p>
                                        </td>
                                        <th><img src="@/assets/img/6.png" style="width: 50px;height: 50px"/></th>
                                        <td>
                                            <p><span id="recommendNum">{{ statistics.recommendNum }}</span></p>
                                            <p>反馈人数</p>
                                        </td>
                                    </tr>
                                </table>
                            </div>
                        </div>
                    </div>
                    <div class="flex-cell flex-cell-r" style="padding-left:0;">
                        <div class="chart-wrapper">
                            <h3 class="chart-title">问答热门排行Top10</h3>
                            <div class="chart-div" id="problemChart">
                                <div class="chart-loader">
                                    <div class="loader"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="flex-row">
                    <div class="flex-cell flex-cell-lc" style="padding-bottom:0;">
                        <div class="chart-wrapper">
                            <h3 class="chart-title">2022文章月度浏览量</h3>
                            <div class="chart-div" id="trendChart">
                                <div class="chart-loader">
                                    <div class="loader"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="flex-cell flex-cell-r" style="padding-bottom:0;">
                        <div class="chart-wrapper">
                            <h3 class="chart-title">编程语言分类</h3>
                            <div class="chart-div" id="codeChart">
                                <div class="chart-loader">
                                    <div class="loader"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import $ from 'jquery'
import * as echarts from 'echarts'
import {onMounted, ref} from "vue";
import {countByMonth, getStatistics, getTopTenArticle, getTopTenLabel, getTopTenProblem} from "@/api/statistics";
import {CountUp} from 'countup.js';


//数据汇总
const statistics = ref({
    browseNum: 0,
    registerNum: 0,
    onlineNum: 0,
    articleNum: 0,
    problemNum: 0,
    recommendNum: 0
})

//文章列表
const articleList = ref()

//可视化
const visual = () => {
    //获取当天日期
    const now = new Date();
    const year = now.getFullYear();
    const month = now.getMonth() + 1;
    const day = now.getDate();
    $("#nowDate").html(year + "年" + month + "月" + day + "日");
    //获取统计数据
    getStatistics().then((res) => {
        statistics.value.browseNum = res.data.data.map.browseNum
        statistics.value.registerNum = res.data.data.map.registerNum
        statistics.value.onlineNum = res.data.data.map.onlineNum
        statistics.value.articleNum = res.data.data.map.articleNum
        statistics.value.problemNum = res.data.data.map.problemNum
        statistics.value.recommendNum = res.data.data.map.recommendNum
        const options = {
            duration: 5,
            useEasing: true,
            useGrouping: true,
            separator: ',',
            decimal: '.',
        };
        const demo = new CountUp('myNumber', 0, options);
        demo.start();
    })

    //获取文章排行数据
    const rankChart = echarts.init(document.getElementById("rankChart") as any, "shine");
    const rankChartOpt = {
        tooltip: {
            trigger: "axis",
            axisPointer: {
                type: "shadow"
            },
            formatter: function (params: any) {
                const param = params[0];
                const marker = '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#e6b600;"></span>';
                return param.name + "<br />" +
                    marker + "排名：" + (param.dataIndex + 1) + "<br />" +
                    marker + "浏览量：" + param.value;
            }
        },
        grid: {
            top: 10,
            bottom: 10,
            left: 100
        },
        xAxis: {
            show: false,
            type: "value"
        },
        yAxis: {
            type: "category",
            inverse: true,
            axisLine: {show: false},
            axisTick: {show: false},
            axisLabel: {
                fontSize: 12,
                color: "#b0c2f9"
            }
        },
        series: [{
            name: "文章浏览量排行榜",
            type: "bar",
            barCategoryGap: "60%",
            label: {
                show: true,
                position: "right",
                fontSize: 12,
                color: "#188df0",
                emphasis: {
                    color: "#e6b600"
                }
            },
            itemStyle: {
                normal: {
                    color: new echarts.graphic.LinearGradient(
                        0, 1, 1, 1,
                        [
                            {offset: 0, color: '#b0c2f9'},
                            {offset: 0.5, color: '#188df0'},
                            {offset: 1, color: '#185bff'}
                        ]
                    )
                },
                emphasis: {
                    color: new echarts.graphic.LinearGradient(
                        0, 1, 1, 1,
                        [
                            {offset: 0, color: '#b0c2f9'},
                            {offset: 0.7, color: '#e6b600'},
                            {offset: 1, color: '#ceac09'}
                        ]
                    )
                }
            }
        }]
    };
    rankChart.setOption(rankChartOpt);
    getTopTenArticle().then((res) => {
        articleList.value = res.data.data.list
        $("#rankChart").addClass("chart-done");
        const xData = [];
        const yData = [];
        for (let i in articleList.value) {
            xData.push(articleList.value[i].views);
            if (articleList.value[i].title.length <= 7) {
                yData.push(articleList.value[i].title)
            } else {
                yData.push(articleList.value[i].title.substring(0, 7) + "...")
            }
        }
        rankChart.setOption({
            yAxis: {
                data: yData
            },
            series: [{
                name: "浏览量",
                data: xData
            }]
        });
    })

    //获取问答排行数据
    const problemChart = echarts.init(document.getElementById("problemChart") as any, "shine");
    const problemChartOpt = {
        tooltip: {
            trigger: "axis",
            axisPointer: {
                type: "shadow"
            },
            formatter: function (params: any) {
                console.log(params)
                const param = params[0];
                const marker = '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#e6b600;"></span>';
                return param.name + "<br />" +
                    marker + "排名：" + (param.dataIndex + 1) + "<br />" +
                    marker + "浏览量：" + param.value;
            }
        },
        grid: {
            top: 10,
            bottom: 10,
            left: 100
        },
        xAxis: {
            show: false,
            type: "value"
        },
        yAxis: {
            type: "category",
            inverse: true,
            axisLine: {show: false},
            axisTick: {show: false},
            axisLabel: {
                fontSize: 12,
                color: "#b0c2f9"
            }
        },
        series: [{
            name: "问答浏览量排行榜",
            type: "bar",
            barCategoryGap: "60%",
            label: {
                show: true,
                position: "right",
                fontSize: 12,
                color: "#188df0",
                emphasis: {
                    color: "#e6b600"
                }
            },
            itemStyle: {
                normal: {
                    color: new echarts.graphic.LinearGradient(
                        0, 1, 1, 1,
                        [
                            {offset: 0, color: '#b0c2f9'},
                            {offset: 0.5, color: '#188df0'},
                            {offset: 1, color: '#185bff'}
                        ]
                    )
                },
                emphasis: {
                    color: new echarts.graphic.LinearGradient(
                        0, 1, 1, 1,
                        [
                            {offset: 0, color: '#b0c2f9'},
                            {offset: 0.7, color: '#e6b600'},
                            {offset: 1, color: '#ceac09'}
                        ]
                    )
                }
            }
        }]
    };
    problemChart.setOption(problemChartOpt);
    getTopTenProblem().then((res) => {
        $("#problemChart").addClass("chart-done");
        const xData = [];
        const yData = [];
        for (let i in res.data.data.list) {
            xData.push(res.data.data.list[i].views)
            if (res.data.data.list[i].title.length <= 7) {
                yData.push(res.data.data.list[i].title)
            } else {
                yData.push(res.data.data.list[i].title.substring(0, 7) + "...")
            }
        }
        problemChart.setOption({
            yAxis: {
                data: yData
            },
            series: [{
                name: "浏览量",
                data: xData
            }]
        });
    })

    //获取月度股票情况数据
    const trendChart = echarts.init(document.getElementById("trendChart") as any, "shine");
    const trendChartOpt = {
        tooltip: {
            trigger: "axis",
            axisPointer: {
                type: "none"
            }
        },
        legend: {
            left: "center",
            bottom: 3,
            itemWidth: 15,
            itemHeight: 10,
            textStyle: {
                fontSize: 12,
                color: "#b0c2f9"
            },
            data: ["月上传量", "日上传量"]
        },
        grid: {
            top: 40,
            bottom: 50,
            left: 60,
            right: 60
        },
        xAxis: {
            type: "category",
            axisLine: {
                lineStyle: {color: "#b0c2f9"}
            },
            axisTick: {show: false},
            axisLabel: {
                fontSize: 12,
                color: "#b0c2f9"
            }
        },
        yAxis: [{
            name: "数量",
            type: "value",
            splitNumber: 5,
            axisLine: {
                lineStyle: {color: "#b0c2f9"}
            },
            splitLine: {show: false},
            axisTick: {color: "#b0c2f9"},
            axisLabel: {
                fontSize: 12,
                color: "#b0c2f9",
                formatter: (value: string) => {
                    return value;
                }
            }
        }, {
            name: "",
            type: "value",
            splitNumber: 5,
            maxInterval: "",
            minInterval: 5,
            interval: 5,
            axisLine: {
                lineStyle: {color: "#b0c2f9"}
            },
            splitLine: {show: false},
            axisTick: {color: "#b0c2f9"},
            axisLabel: {
                fontSize: 12,
                color: "#b0c2f9"
            }
        }],
        visualMap: {
            show: false,
            seriesIndex: 2,
            dimension: 0,
            pieces: [{
                lte: 9,
                color: "rgba(176, 58, 91, 1)"
            }, {
                gt: 9,
                lte: 11,
                color: "rgba(176, 58, 91, 0.5)"
            }]
        },
        series: [{
            name: "月上传量",
            type: "pictorialBar",
            symbol: 'path://d="M150 50 L130 130 L170 130  Z"',
            barCategoryGap: "40%",
            itemStyle: {
                color: function (params: any) {
                    if (params.dataIndex >= 10) {
                        return "rgba(119, 96, 246, 0.5)";
                    }
                    return "rgba(119, 96, 246, 1)";
                }
            },
            markPoint: {
                itemStyle: {
                    color: "rgba(119, 96, 246, 1)"
                },
                data: [{
                    name: "最大值",
                    type: "max"
                }]
            },
            markLine: {
                lineStyle: {
                    color: "rgba(119, 96, 246, 1)"
                },
                label: {
                    position: "middle",
                    formatter: "月度上传发布量：{c}"
                },
                data: [{
                    name: "平均值",
                    type: "average"
                }]
            }
        }, {
            name: "总上传量",
            type: "pictorialBar",
            symbol: 'path://d="M150 50 L130 130 L170 130  Z"',
            barCategoryGap: "40%",
            itemStyle: {
                color: function (params: any) {
                    if (params.dataIndex >= 10) {
                        return "rgba(230, 182, 0, 0.5)";
                    }
                    return "rgba(230, 182, 0, 1)";
                }
            },
            markPoint: {
                itemStyle: {
                    color: "rgba(230, 182, 0, 1)"
                },
                data: [{
                    name: "最大值",
                    type: "max"
                }]
            },
            markLine: {
                lineStyle: {
                    color: "rgba(230, 182, 0, 1)"
                },
                label: {
                    position: "middle",
                    formatter: "日度平均上传量：{c}"
                },
                data: [{
                    name: "平均值",
                    type: "average"
                }]
            }
        }, {
            name: "日上传量",
            type: "line",
            yAxisIndex: 1
        }]
    };
    trendChart.setOption(trendChartOpt);
    countByMonth("2022").then((res) => {
        console.log(res.data.data.list)
        $("#trendChart").addClass("chart-done");
        const xData = [];
        const yData1 = [];
        const yData2 = [];
        const yData3 = [];
        for (let i in res.data.data.list) {
            xData.push(res.data.data.list[i].month + "月")
            yData1.push(res.data.data.list[i].count)
            yData2.push(res.data.data.list[i].max_count)
            yData3.push((res.data.data.list[i].count / 30).toFixed(3))
        }
        trendChart.setOption({
            xAxis: {
                data: xData,
            },
            series: [{
                name: "月上传量",
                data: yData1
            }, {
                name: "最大上传量",
                data: yData2
            }, {
                name: "日上传量",
                data: yData3
            }]
        });
    })

    //获取编程语言分类数据
    const codeChart = echarts.init(document.getElementById("codeChart") as any, "shine");
    const codeChartOpt = {
        tooltip: {
            trigger: "item",
            formatter: "{b0}<br />使用量：{c0}<br />占比：{d0}%"
        },
        legend: {
            type: "scroll",
            orient: "vertical",
            padding: 0,
            top: 15,
            right: 0,
            itemGap: 5,
            itemWidth: 10,
            itemHeight: 10,
            textStyle: {
                fontSize: 10,
                color: "#b0c2f9"
            }
        },
        series: [{
            name: "编程语言分类",
            type: "pie",
            center: ["47%", "55%"],
            radius: ["30%", "85%"]
        }]
    };
    codeChart.setOption(codeChartOpt);
    getTopTenLabel().then((res) => {
        $("#codeChart").addClass("chart-done");
        const chartData = [];
        for (let i in res.data.data.list) {
            chartData.push({
                name: res.data.data.list[i].tagName,
                value: res.data.data.list[i].usageCount
            });
        }
        codeChart.setOption({
            series: [{
                name: "编程语言分类",
                data: chartData
            }]
        });
    })

    //浏览器窗口大小变化时，重置报表大小
    $(window).resize(function () {
        rankChart.resize();
        problemChart.resize()
        trendChart.resize();
        codeChart.resize();
    });
}

onMounted(() => {
    visual()
})
</script>

<style lang="less" scoped>

.body {
  width: 100%;
  height: 100%;
  min-width: 1200px;
  min-height: 600px;
  overflow: hidden;
  position: relative;
  font-family: "Microsoft Yahei", Arial, sans-serif;
  background: rgb(40, 30, 47) url("@/assets/img/bg.png") 0 0 / 100% 100% no-repeat;
}

/* layout */
#header {
  position: relative;
  height: 72px;
  background: url("@/assets/img/header.png") 0 0 / 100% 100% no-repeat;
  overflow: hidden;
}

.header-title {
  line-height: 64px;
  text-align: center;
  font-size: 34px;
  font-weight: 400;
  color: #fff;
}

.header-info {
  position: absolute;
  top: 32px;
  font-size: 18px;
  color: #73aae5;
}

.header-info-l {
  left: 20px;
}

.header-info-r {
  right: 20px;
}

#footer {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 28px;
  background: url("@/assets/img/footer.png") 0 0 / 100% 100% no-repeat;
}

#container {
  position: absolute;
  top: 72px;
  bottom: 22px;
  left: 0;
  right: 0;
}

#flexCon {
  height: 100%;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
}

.flex-row {
  -webkit-flex: 1;
  -ms-flex: 1;
  flex: 1;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
}

.flex-cell {
  -webkit-flex: 1;
  -ms-flex: 1;
  flex: 1;
  padding: 15px;
}

.flex-cell-l,
.flex-cell-r {
  -webkit-flex: 2;
  -ms-flex: 2;
  flex: 2;
}

.flex-cell-c {
  -webkit-flex: 3;
  -ms-flex: 3;
  flex: 3;
}

.flex-cell-lc {
  -webkit-flex: 5;
  -ms-flex: 5;
  flex: 5;
}

.chart-wrapper {
  position: relative;
  height: 100%;
}

.chart-title {
  height: 32px;
  font-size: 22px;
  font-weight: normal;
  color: #9aa8d4;
}

.chart-div {
  position: absolute;
  top: 32px;
  bottom: 0;
  left: 0;
  right: 0;
}

.data-t {
  table-layout: fixed;
  width: 100%;
  height: 100%;
  border-collapse: collapse;
}

.data-t th,
.data-t td {
  min-height: 48px;
}

.data-t th {
  width: 60px;
  text-align: center;
  background: url("@/assets/img/icon-bg.png") center / 100% no-repeat;
}

.data-t th img {
  width: 30px;
  height: 30px;
}

.data-t td {
  padding-left: 15px;
}

.data-t p {
  margin: 5px 0;
  line-height: 1;
  font-size: 14px;
  color: #b0c2f9;
}

.data-t p span {
  font-size: 32px;
  font-weight: bold;
  color: #fff;
}

/* media query */
@media (max-width: 1900px) {
  #header {
    height: 48px;
  }

  .header-title {
    line-height: 42px;
    font-size: 24px;
  }

  .header-info {
    top: 17px;
    font-size: 14px;
  }

  .header-info-l {
    left: 15px;
  }

  .header-info-r {
    right: 15px;
  }

  .flex-cell {
    padding: 10px;
  }

  .chart-title {
    height: 24px;
    font-size: 18px;
  }

  .chart-div {
    top: 24px;
  }

  .data-t p span {
    font-size: 24px;
  }

  #footer {
    height: 16px;
  }

  #container {
    top: 48px;
    bottom: 12px;
  }
}

/* chart-loader */
.chart-loader {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 99;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0);
  transition: all .8s;
}

.chart-loader .loader {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 60px;
  height: 60px;
  margin: -30px 0 0 -30px;
  border: 3px solid transparent;
  border-top-color: #3498db;
  border-radius: 50% !important;
  -webkit-animation: spin 2s linear infinite;
  animation: spin 2s linear infinite;
}

.chart-loader .loader:before {
  content: "";
  position: absolute;
  top: 3px;
  left: 5px;
  right: 5px;
  bottom: 5px;
  border: 3px solid transparent;
  border-top-color: #e74c3c;
  border-radius: 50% !important;
  -webkit-animation: spin 3s linear infinite;
  animation: spin 3s linear infinite;
}

.chart-loader .loader:after {
  content: "";
  position: absolute;
  top: 9px;
  left: 10px;
  right: 10px;
  bottom: 10px;
  border: 3px solid transparent;
  border-top-color: #f9c922;
  border-radius: 50% !important;
  -webkit-animation: spin 1.5s linear infinite;
  animation: spin 1.5s linear infinite;
}

.chart-done .chart-loader {
  display: none;
}

@-webkit-keyframes spin {
  0% {
    -webkit-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    transform: rotate(0deg)
  }
  100% {
    -webkit-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
    transform: rotate(360deg)
  }
}

@keyframes spin {
  0% {
    -webkit-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    transform: rotate(0deg)
  }
  100% {
    -webkit-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
    transform: rotate(360deg)
  }
}
</style>